/*****************************************************************
*
*	Netcare Agent Project
*		Copyright(C) 2010, Wicresoft EKA. All Rights Reserved.
*
*	Authors:
*		Miles Chen (milesch@wicresoft.com)
*		TingRong Shi (trshi@wicresoft.com)
*
*	Part of the product code depends on gSOAP under GPL license
*		Copyright(C) 2000-2010, Robert van Engelen, Genivia Inc. All Rights Reserved.
*
*****************************************************************/
#include <string>
#include <vector>
#include <algorithm>


#include "netcare.h"
#include "soapHostSoap12ServiceImpl.h"
#include "SharedInfo.rs"
#include "misc.h"

USING_STD;
USING_NETCARE_AGENT;


soapHostSoap12ServiceImpl::soapHostSoap12ServiceImpl(void) : _pArrayOfProcessInfo(NULL), _pSystemInfo(NULL), _pAgentInfo(NULL)
{
	//LogDebug(_T("soapHostSoap12ServiceImpl::ctor()"));
}


soapHostSoap12ServiceImpl::~soapHostSoap12ServiceImpl(void)
{
	Dispose();
	LogDebug(_T("soapHostSoap12ServiceImpl::~ctor()"));
}

void soapHostSoap12ServiceImpl::Dispose()
{
	if(_pArrayOfProcessInfo)
	{
		vector<class ns1__ProcessInfo*>& p = _pArrayOfProcessInfo->ProcessInfo;
		for(int i=0; i<(int)p.size(); i++)
		{
			delete p[i]->ImageName;
			delete p[i]->FullPath;
			delete p[i];
		}
		delete _pArrayOfProcessInfo;
		_pArrayOfProcessInfo = NULL;
	}
	if(_pArrayOfServiceInfo)
	{
		vector<ns1__ServiceInfo*>& p = _pArrayOfServiceInfo->ServiceInfo;
		for( int i = 0 ; i < (int)p.size() ; i++ )
		{
			delete p[i]->DisplayName;
			delete p[i]->ShortName;
			delete p[i];
		}
		delete _pArrayOfServiceInfo;
		_pArrayOfServiceInfo = NULL;
	}
	if(_pSystemInfo)
	{
		delete _pSystemInfo->Manufactory;
		delete _pSystemInfo->OperatingSystem;
		delete _pSystemInfo->Product;
		delete _pSystemInfo->Version;
		delete _pSystemInfo;
		_pSystemInfo = NULL;
	}
	if(_pAgentInfo)
	{
		delete _pAgentInfo;
		_pAgentInfo = NULL;
	}
}


/// Web service operation 'GetProcesses' (returns error code or SOAP_OK)
int soapHostSoap12ServiceImpl::GetProcesses(_ns1__GetProcesses *req, _ns1__GetProcessesResponse *res)
{
	LogDebug(_T("Entering soapHostSoap12ServiceImpl::GetProcesses"));
	int stat = SOAP_OK;
	Dispose();
	//
	_pArrayOfProcessInfo = new ns1__ArrayOfProcessInfo();
	res->GetProcessesResult = _pArrayOfProcessInfo;

	vector<class CProcess*>* list = CProcess::GetProcesses();
	if(list)
	{
		for(int i=0; i<(int)list->size(); i++)
		{
			ns1__ProcessInfo* p = new ns1__ProcessInfo();
			{
				p->ProcessId = (*list)[i]->ProcessId;
	#ifdef WIN32
				p->ImageName = new wstring((*list)[i]->ImageName);
				p->FullPath = new wstring((*list)[i]->FullPath);
	#else
				p->ImageName = new string((*list)[i]->ImageName);
				p->FullPath = new string((*list)[i]->FullPath);
	#endif
				p->NonpagedSystemMemorySize64 = (*list)[i]->NonpagedSystemMemorySize64;
				p->PagedMemorySize64 = (*list)[i]->PagedMemorySize64;
				p->PeakPagedMemorySize64 = (*list)[i]->PeakPagedMemorySize64;
				p->PeakVirtualMemorySize64 = (*list)[i]->PeakVirtualMemorySize64;
				p->PrivateMemorySize64 = (*list)[i]->PrivateMemorySize64;
			}
			res->GetProcessesResult->ProcessInfo.push_back(p);
			delete (*list)[i];
		}
		delete list;
	}
	else
	{
		stat = SOAP_FAULT;
		LogError(_T("Cannot query system processes"));
		soap_receiver_fault(res->soap, "Cannot query system processes due to system internal error or you don't have sufficient permission.", "Cannot query system processes");
	}

	LogDebug(_T("Leaving soapHostSoap12ServiceImpl::GetProcesses"));
	return stat;
}

/// Web service operation 'KillProcess' (returns error code or SOAP_OK)
int soapHostSoap12ServiceImpl::KillProcess(_ns1__KillProcess *req, _ns1__KillProcessResponse *res)
{
	LogDebug(_T("Entering soapHostSoap12ServiceImpl::KillProcess"));
	int stat = SOAP_OK;
	Dispose();
	//
	CProcess p = req->pid;
	if(!p.Kill())
	{
		stat = SOAP_FAULT;
		LogError(_T("Cannot kill process, pid=%d, name=%s, path=%s"), p.ProcessId, p.ImageName.c_str(), p.FullPath.c_str());
		soap_receiver_fault(res->soap, "Cannot kill process due to the specific process has existed or you don't have sufficient permission.", "Cannot kill process");
	}

	LogDebug(_T("Leaving soapHostSoap12ServiceImpl::KillProcess"));
	return stat;
}

/// Web service operation 'GetSystemInfo' (returns error code or SOAP_OK)
int soapHostSoap12ServiceImpl::GetSystemInfo(_ns1__GetSystemInfo *req, _ns1__GetSystemInfoResponse *res)
{
	LogDebug(_T("Entering soapHostSoap12ServiceImpl::GetSystemInfo"));
	int stat = SOAP_OK;
	Dispose();

	_pSystemInfo = new ns1__SystemInfo();
	res->GetSystemInfoResult = _pSystemInfo;
	CSystemInfo info;
#ifdef WIN32
	res->GetSystemInfoResult->OperatingSystem = new wstring(info.OperatingSystem);
	res->GetSystemInfoResult->Product = new wstring(info.Product);
	res->GetSystemInfoResult->Manufactory = new wstring(info.Manufactory);
	res->GetSystemInfoResult->Version = new wstring(info.Version);
	res->GetSystemInfoResult->ComputerName = new wstring(info.ComputerName);
	res->GetSystemInfoResult->Architecture = new wstring(info.Architecture);
#else
	res->GetSystemInfoResult->OperatingSystem = new string(info.OperatingSystem);
	res->GetSystemInfoResult->Product = new string(info.Product);
	res->GetSystemInfoResult->Manufactory = new string(info.Manufactory);
	res->GetSystemInfoResult->Version = new string(info.Version);
	res->GetSystemInfoResult->ComputerName = new string(info.ComputerName);
	res->GetSystemInfoResult->Architecture = new string(info.Architecture);
#endif

	LogDebug(_T("Leaving soapHostSoap12ServiceImpl::GetSystemInfo"));
	return SOAP_OK;
}

/// Web service operation 'GetAgentInfo' (returns error code or SOAP_OK)
int soapHostSoap12ServiceImpl::GetAgentInfo(_ns1__GetAgentInfo *req, _ns1__GetAgentInfoResponse *res)
{
	LogDebug(_T("Entering soapHostSoap12ServiceImpl::GetAgentInfo"));
	Dispose();
	//
#ifdef WIN32
	wchar_t* p = _ANSI(AGENT_FULL_INFO);
	res->GetAgentInfoResult = new wstring(p);
	delete[] p;
#else
	res->GetAgentInfoResult = new string(AGENT_FULL_INFO);
#endif

	LogDebug(_T("Leaving soapHostSoap12ServiceImpl::GetAgentInfo"));
	return SOAP_OK;
}

/// Web service operation 'RestartService' (returns error code or SOAP_OK)
int soapHostSoap12ServiceImpl::RestartService(_ns1__RestartService *req, _ns1__RestartServiceResponse *res)
{
	LogDebug(_T("Entering soapHostSoap12ServiceImpl::RestartService"));
	Dispose();

	CServiceOperation op;
	int returnValue = SOAP_CLI_FAULT;
	if(op.RestartService(req->SerivceName->c_str()))
		returnValue = SOAP_OK;

	LogDebug(_T("Leaving soapHostSoap12ServiceImpl::RestartService"));
	return returnValue;
}

/// Web service operation 'RestartOS' (returns error code or SOAP_OK)
int soapHostSoap12ServiceImpl::RestartOS(_ns1__RestartOS *req, _ns1__RestartOSResponse *res)
{
	LogDebug(_T("Entering soapHostSoap12ServiceImpl::RestartOS"));
	Dispose();

	COsOperation op;
	int returnValue = SOAP_CLI_FAULT;
	if(op.RestartOS())
		returnValue = SOAP_OK;

	LogDebug(_T("Leaving soapHostSoap12ServiceImpl::RestartOS"));
	return returnValue;
}

/// Web service operation 'MemoryRelease' (returns error code or SOAP_OK)
int soapHostSoap12ServiceImpl::MemoryRelease(_ns1__MemoryRelease *req, _ns1__MemoryReleaseResponse *res)
{
	//TODO:
	LogDebug(_T("Entering soapHostSoap12ServiceImpl::MemoryRelease"));
	Dispose();
	//
	Netcare::Agent::CMemoryRelease mr;
	if(mr.Release())
	{
		LogDebug(_T("Leaving soapHostSoap12ServiceImpl::MemoryRelease SOAP_OK"));
		return SOAP_OK;
	}
	else
	{
		LogDebug(_T("Leaving soapHostSoap12ServiceImpl::MemoryRelease SOAP_CLI_FAULT"));
		return SOAP_CLI_FAULT;
	}
}

/// Web service operation 'DiskRelease' (returns error code or SOAP_OK)
int soapHostSoap12ServiceImpl::DiskRelease(_ns1__DiskRelease *req, _ns1__DiskReleaseResponse *res)
{
	LogDebug(_T("Entering soapHostSoap12ServiceImpl::DiskRelease"));
	Dispose();
	static Netcare::Agent::CDiskRelease dr;
	int rs = dr.DiskDefrag(req->Commend);
	
	res->DiskReleaseResult=ns1__ReturnValue(rs);

	LogDebug(_T("Leaving soapHostSoap12ServiceImpl::DiskRelease"));
	return SOAP_OK;
}

/// Web service operation 'EnumServices' (returns error code or SOAP_OK)
int soapHostSoap12ServiceImpl::EnumServices(_ns1__EnumServices *req, _ns1__EnumServicesResponse *res)
{
	LogDebug(_T("Entering soapHostSoap12ServiceImpl::EnumServices"));
	Dispose();
	int returnValue = SOAP_OK;
	_pArrayOfServiceInfo = new ns1__ArrayOfServiceInfo();
	res->EnumServicesResult = _pArrayOfServiceInfo;

	vector<CSysService*>* list = CServiceOperation::GetServices();
	if(list)
	{
		for( int i = 0 ; i < (int)list->size() ; i++ )
		{
			ns1__ServiceInfo* s = new ns1__ServiceInfo();
			s->PID = (*list)[i]->PID;
			s->Status = (ns1__ServiceStatus)(*list)[i]->Status;
#ifdef WIN32
			s->ShortName = new wstring((*list)[i]->ShortName);
			s->DisplayName = new wstring((*list)[i]->DisplayName);
#else
			s->ShortName = new string((*list)[i]->ShortName);
			s->DisplayName = new string((*list)[i]->DisplayName);
#endif
			res->EnumServicesResult->ServiceInfo.push_back(s);
			delete (*list)[i];
		}
		delete list;
	}
	else
	{
		returnValue = SOAP_CLI_FAULT;
		LogError(_T("Cannot query system services"));
		soap_receiver_fault(res->soap, "Cannot query system services due to system internal error or you don't have sufficient permission.", "Cannot query system services");
	}
	LogDebug(_T("Leaving soapHostSoap12ServiceImpl::EnumServices"));
	return returnValue;
}
